import Taro, { Component } from '@tarojs/taro'
import {View, ScrollView, Text, Image, Button } from '@tarojs/components'
import { Loading } from '@components'
import { connect } from '@tarojs/redux'
import { AtFloatLayout, AtInputNumber } from 'taro-ui'
import * as actions from '@actions/item'
import { dispatchCartSave } from '@actions/cart'
import { getWindowHeight } from '@utils/style'
import jump from '@utils/jump'
import classNames from 'classnames'
import Gallery from './gallery'
import InfoBase from './info-base'
import InfoParam from './info-param'
import Detail from './detail'
import Footer from './footer'
import './item.scss'

@connect(state => state.item, { ...actions, dispatchCartSave })
class Item extends Component {
  config = {
    navigationBarTitleText: '商品详情',
    enablePullDownRefresh: true,
    backgroundTextStyle: 'dark'
  }

  constructor(props) {
    super(props)
    this.state = {
      loading: true,
      openSpec: false,
      openServer: false,
      baseInfo: {},
      specList: [],
      attrList: [],
      skuMap: {},
      selectId: 0,
      cnt: 1,
      specName: '',
      sellingPrice: '',
      selected: []
    }
    this.itemId = parseInt(this.$router.params.itemId)
  }

  componentDidMount() {
    this.loadItem()
  }

  onShareAppMessage() { }

  onPullDownRefresh() {
    this.loadItem()
    Taro.stopPullDownRefresh()
  }

  loadItem() {
    this.props.dispatchItem({ itemId: this.itemId }).then((data) => {
      let specList = this.initSpecList(data.specList, data.skuMap);
      let selected = []
      specList.forEach(() => {
        selected.push('-1')
      })
      this.setState({
        loading: false,
        sellingPrice: data.baseInfo.sellingPrice,
        baseInfo: data.baseInfo,
        specList: specList,
        attrList: data.attrList,
        skuMap: data.skuMap,
        selected: selected
      })
    })
  }

  initSpecList = (specList, skuMap) => {
    let optionIdSet = new Set()
    Object.keys(skuMap).filter(key => skuMap[key].valid)
      .map(key => {
        key.split('^').forEach(x => optionIdSet.add(x))
      })
    specList.forEach(spec => {
      spec.options.forEach(option => {
        option.valid = optionIdSet.has(option.id)
        option.active = false
      })
    })
    return specList
  }

  handleCloseSpec = () => {
    this.setState({ openSpec: false })
  }

  handleOpenSpec = () => {
    this.setState({ openSpec: true })
  }

  handleCloseServer = () => {
    this.setState({ openServer: false })
  }

  handleOpenServer = () => {
    this.setState({ openServer: true })
  }

  clickSpecOption = (specOption, index) => {
    // 是否可以点击
    if (!specOption.valid) {
      return
    }
    let selected = this.state.selected
    if (specOption.active) {
      selected[index] = '-1'
    } else {
      selected[index] = specOption.id
    }

    const { skuMap = {}, specList = [], baseInfo = {} } = this.state
    // 选中状态设置
    specList[index].options.forEach(option => { option.active = option.id == selected[index] })

    // 不可达设置
    let array = []
    selected.forEach(i => {
      if (i && i != '-1') {
        array.push(i)
      }
    })
    let pathArray = []
    Object.keys(skuMap).filter(key => skuMap[key].valid).map(key => pathArray.push(key.split('^')))
    let len = specList.length
    for (let i = 0; i < len; i++) {
      if (i != index) {
        specList[i].options.forEach(option => {
          option.valid = this.isSpecOptionValid(option, i, selected, pathArray)
        })
      }
    }

    let specName = ''
    let sellingPrice = ''
    let selectId =  0
    // 是否全部选择完成
    if (selected.every(s => s != '-1')) {
      const selectedSpec = Object.keys(selected).sort((a, b) => a - b)
      const id = selectedSpec.map(key => selected[key]).join('^')
      const sku = skuMap[id]
      selectId = id
      specName = sku.skuSpecName
      sellingPrice = sku.sellingPrice
    } else {
      sellingPrice = baseInfo.sellingPrice
    }

    this.setState({
      specList: specList,
      selected: selected,
      selectId: selectId,
      sellingPrice: sellingPrice,
      specName: specName
    })
  }

  isSpecOptionValid = (option, row, selected, pathArray) => {
    if(selected[row] === option.id) {
      return true
    }
    let array = []
    selected.map((s, index) => {
      if (index == row) {
        array.push(option.id)
      } else if (s != '-1') {
        array.push(s)
      }
    })
    return pathArray.some(path => {
      return array.every(v => path.includes(v))
    })
  }

  isSkuSelected = () => {
    const { selectId, skuMap } = this.state
    const isSelected = !!selectId && skuMap[selectId]
    return isSelected
  }

  handleCntUpdate = (cnt) => {
    this.setState({ cnt: cnt })
  }

  handleBuy = () => {
    if (this.isSkuSelected()) {
      const { skuMap, selectId, cnt } = this.state
      const skuItem = skuMap[selectId]
      let items = []
      items.push({skuId: skuItem.skuId, itemId: this.itemId, itemNum: cnt})
      jump({
        url: '/pages/orderSettlement/orderSettlement',
        payload: {
          fromType: 1,
          items: encodeURIComponent(JSON.stringify(items))
        }
      })
    } else {
      Taro.showToast({
        title: '请选择规格',
        icon: 'none'
      })
    }
  }

  handleAdd = () => {
    if (this.isSkuSelected()) {
      const { skuMap, selectId } = this.state
      const skuItem = skuMap[selectId]
      const payload = {
        skuId: skuItem.skuId,
        itemNum: this.state.cnt
      }
      this.props.dispatchCartSave(payload).then(() => {
        this.handleCloseSpec()
        Taro.showToast({
          title: '加入购物车成功',
          icon: 'none'
        })
      })
    } else {
      Taro.showToast({
        title: '请选择规格',
        icon: 'none'
      })
    }
  }

  render () {
    const { specName, cnt, sellingPrice, baseInfo, specList, attrList } = this.state

    if (this.state.loading) {
      return <Loading />
    }

    let selectedSpecInfo = ''
    if(specName) {
      selectedSpecInfo = '已选择: ' + specName + '; x' + cnt
    }

    return (
      <View className='item'>
        <ScrollView
          scrollY
          className='item__wrap'
          style={{ height: getWindowHeight() }}
        >
          <Gallery list={baseInfo.swiperPics} />
          <InfoBase item={baseInfo} price={{sellingPrice : sellingPrice}} />

          <View className='item-select'>
            <View className='item-select-list' onClick={this.handleOpenSpec}>
              <Text className='item-select-list-label'>规格</Text>
              <Text className='item-select-list-value'>{ selectedSpecInfo || '请选择' }</Text>
              <View className='at-icon at-icon-chevron-right item-select-list-iconmore'></View>
            </View>
            <View className='item-select-list' onClick={this.handleOpenServer}>
              <Text className='item-select-list-label'>配送</Text>
              <Text className='item-select-list-value'>快递</Text>
              <View className='at-icon at-icon-chevron-right item-select-list-iconmore'></View>
            </View>
          </View>

          {attrList && <InfoParam list={attrList} />}
          <Detail html={baseInfo.detailHtml} />
        </ScrollView>

        {/* NOTE Popup 一般的实现是 fixed 定位，但 RN 不支持，只能用 absolute，要注意引入位置 */}
        <AtFloatLayout isOpened={this.state.openSpec} onClose={this.handleCloseSpec}>
          <View className='item-spec'>
            <View className='item-spec__info'>
              <Image className='item-spec__info-img' src={baseInfo.primaryPic} />
              <View className='item-spec__info-wrap'>
                <View className='item-spec__info-price'>
                  <Text className='item-spec__info-price-txt'>
                    {`价格:¥${sellingPrice}`}
                  </Text>
                </View>
                <Text className='item-spec__info-tip'>{this.state.specName || '请选择规格属性'}</Text>
              </View>
            </View>
            <ScrollView scrollY className='item-spec__c'>
              {specList.map((spec, index) => (
                <View key={spec.id} className='item-spec__group'>
                  <Text className='item-spec__group-title'>{spec.name}</Text>
                  <View className='item-spec__group-list'>
                    {spec.options.map(specOption => (
                      <Text
                        key={specOption.id}
                        className={classNames('item-spec__group-list-item', {
                          'item-spec__group-list-item--active': specOption.active,
                          'item-spec__group-list-item--disabled': !specOption.valid
                        })}
                        onClick={this.clickSpecOption.bind(this, specOption, index)}
                      >
                        {specOption.option}
                      </Text>
                    ))}
                  </View>
                </View>
              ))}

              <View className='item-spec__number'>
                <Text className='item-spec__number-title'>数量</Text>
                <AtInputNumber
                  step={1}
                  value={cnt}
                  min={1}
                  onChange={this.handleCntUpdate.bind(this)}
                />
              </View>

            </ScrollView>

            <View className='item-spec__footer'>
              <Button
                className='item-spec__footer-btn item-spec__footer-btn-cart'
                onClick={this.handleAdd}
              >
                <Text className='item-spec__footer-btn-txt'>加入购物车</Text>
              </Button>

              <Button
                className='item-spec__footer-btn item-spec__footer-btn-buy'
                onClick={this.handleBuy}
              >
                <Text className='item-spec__footer-btn-txt'>立即购买</Text>
              </Button>
            </View>
          </View>
        </AtFloatLayout>

        <AtFloatLayout isOpened={this.state.openServer} onClose={this.handleCloseServer}>
          <View className='item__server'>
            <View className='item__server-title'>配送方式</View>
            <View className='item-border' />
            <View className='item__server-name'>
              <View className='marker'></View>
              <Text>物流发货</Text>
            </View>
            <View className='item__server-content'>
              <Text>部分地区无法送达，省份: 西藏自治区、新疆维吾尔自治区、内蒙古自治区、甘肃省、黑龙江省、青海省、吉林省</Text>
            </View>
          </View>
        </AtFloatLayout>

        <View className='item__footer'>
          <Footer onBuy={this.handleOpenSpec} onAdd={this.handleOpenSpec} />
        </View>
      </View>
    )
  }
}

export default Item
